package com.stox.client.ui.javafx.widget;

import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.util.Callback;

import com.stox.client.api.core.ClientFactory;
import com.stox.client.api.data.provider.ScripClient;
import com.stox.client.core.event.ScripSelectionEvent;
import com.stox.client.core.model.intf.HasNavigable;
import com.stox.client.core.model.intf.Navigable;
import com.stox.client.ui.javafx.core.ScripDragEventHandler;
import com.stox.client.ui.javafx.core.util.CSS;
import com.stox.client.ui.javafx.core.util.UI;
import com.stox.shared.event.EventPublisher;
import com.stox.shared.i18n.MessageSource;
import com.stox.shared.model.intf.HasScrip;

public abstract class AbstractHasScripTableView<T extends HasScrip> 
extends TableView<T> 
implements HasNavigable<T>{
	
	private final Class<T> hasScripType;
	
	public AbstractHasScripTableView(Class<T> hasScripType) {
		this.hasScripType = hasScripType;

		setColumnResizePolicy(CONSTRAINED_RESIZE_POLICY);
		getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
		
		setOnDragDetected(new ScripDragEventHandler());
		
		TableColumn<T, String> scripNameColumn = new TableColumn<T, String>(MessageSource.get("Scrip"));
		getColumns().add(scripNameColumn);
		scripNameColumn.setCellFactory(new Callback<TableColumn<T,String>, TableCell<T,String>>() {
			@Override
			public TableCell<T, String> call(
					TableColumn<T, String> param) {
				return new TableCell<T, String>(){
					@Override
					protected void updateItem(String item, boolean empty) {
						UI.style(this, CSS.scripCell);
						super.updateItem(item, empty);
						if(!empty && null != item){
							setText(item);
						}else{
							setText(null);
						}
					}
				};
			}
		});
		scripNameColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<T,String>, ObservableValue<String>>() {
			@Override
			public ObservableValue<String> call(
					CellDataFeatures<T, String> param) {
				if(null == param.getValue().getScrip()){
					param.getValue().setScrip(ClientFactory.getClient(ScripClient.class).findOne(param.getValue().getScripId()));
				}
				if(null != param.getValue().getScrip()){
					return new ReadOnlyObjectWrapper<>(param.getValue().getScrip().getName());
				}
				return null;
			}
		});
		
		
		
		addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>(){
		@Override
		public void handle(MouseEvent event) {
			if(MouseButton.PRIMARY.equals(event.getButton()) && 2 == event.getClickCount()){
				publishEvent();
			}
		}
	});
	}
	
	@Override
	public Navigable<T> getNavigable() {
		return new TableViewNavigableDecorator<T>(this, hasScripType);
	}
	
	public void publishEvent(){
		EventPublisher.publishEvent(new ScripSelectionEvent(this, getNavigable()));
	}
	/*
	@Override
	public Scrip from(T hasScrip) {
		if(null != hasScrip){
			if(null == hasScrip.getScrip() && null != hasScrip.getScripId()){
				hasScrip.setScrip(ClientFactory.getClient(ScripClient.class).findOne(hasScrip.getScripId()));
			}
			return hasScrip.getScrip();
		}
		return null;
	}
	
	@Override
	public T to(Scrip scrip) {
		if(null != scrip && null != scrip.getId()){
			for(T hasScrip : getItems()){
				if(scrip.getId().equals(hasScrip.getScripId())){
					return hasScrip;
				}
			}
		}
		return null;
	}*/
	
}